package server_V2;
// <editor-fold defaultstate="collapsed" desc="Imports">
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import lib.FileHandler;
import lib.StreamSocket;
import serverMain.ServerCounter;
// </editor-fold> 

/**
 * @file ProtocallThread.java
 *
 * @version 0.1
 * @author Chris Sewell 10008342
 */
public class ProtocallThreadV2 extends Thread {
    // <editor-fold defaultstate="collapsed" desc="Attributes">

    StreamSocket clientStream;
    String clientInput;
    ServerCounter downloadCounter;
    FileHandler file;
    Random portGenerator = new Random();
    ServerSocket fileServer;
    byte[] data;
    boolean more = true;
    int fileServerPort;
    ServerDataTransferThread dx;
    // </editor-fold> 
    // <editor-fold defaultstate="collapsed" desc="Constructors">

    public ProtocallThreadV2(Socket acceptedSocket, ServerCounter downloadCounter) throws IOException {
        clientStream = new StreamSocket(acceptedSocket);
        this.downloadCounter = downloadCounter;
        fileServerPort = portGenerator.nextInt(4000) + 1000;
        fileServer = new ServerSocket(fileServerPort);
    }
    // </editor-fold> 
    // <editor-fold defaultstate="collapsed" desc="Methods">

    //Terms of refrence input validator
    public boolean validateClientRefInput(String clientInput) {
        if ((clientInput.equalsIgnoreCase("Y"))
                || (clientInput.equalsIgnoreCase("N"))) {
            return true;
        } else {
            clientStream.sendString("Invalid input --- Terms of refrence. Do you accept? Y or N");
            return false;
        }
    }

    //File/Description input validator
    public boolean validateClientMenuInput(String clientInput) {
        if ((clientInput.equalsIgnoreCase("1"))
                || (clientInput.equalsIgnoreCase("2"))
                || (clientInput.equalsIgnoreCase("3"))) {
            return true;
        } else {
            clientStream.sendString("Invalid choice --- 1. computer program 2. picture 3. e-book");
            return false;
        }
    }

    //Another file/description input validator
    public boolean validateClientAnotherInput(String clientInput) {
        if ((clientInput.equalsIgnoreCase("Y"))
                || (clientInput.equalsIgnoreCase("N"))) {
            return true;
        } else {
            clientStream.sendString("Invalid input --- Another? Y or N");
            return false;
        }
    }
    @Override
    public void run() {
        System.out.print("New client connected, client " + clientStream.displayDetail() + " now connected\n");
        clientStream.sendString("Terms of refrence. Do you accept? Y or N");

        do { //Terms of service        
            clientInput = clientStream.recieveString();
        } while (!validateClientRefInput(clientInput));

        if (clientInput.equalsIgnoreCase("N")) {
            try {
                //Close connection if N
                clientStream.kill();
            } catch (IOException ex) {
                Logger.getLogger(ProtocallThreadV2.class.getName()).log(Level.SEVERE, null, ex);
            }
            //Client has disconnected
            System.out.print("Client " + clientStream.displayDetail() + " has disconnected\n");
            more = false;
        }

        while (more == true) {
            clientStream.sendString("1. computer program 2. picture 3. e-book");
            do { //Main menu
                clientInput = clientStream.recieveString();
            } while (!validateClientMenuInput(clientInput));

            int clientSelection = Integer.parseInt(clientInput);
            switch (clientSelection) {//Process choice
                case 1: {
                    clientStream.sendString("Valid");
                    clientStream.sendString("myProgram.jar");
                    try {
                        file = new FileHandler("myProgram.jar");//Send file name
                    } catch (FileNotFoundException ex) {
                        Logger.getLogger(ProtocallThreadV2.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    data = file.readFromFile();
                    clientStream.sendString(Integer.toString(data.length));//Send file length
                    clientStream.sendString(Integer.toString(fileServerPort));//Send port
                    try {
                        StreamSocket uploadSocket = new StreamSocket(fileServer.accept());//Accept new file socket
                        dx = new ServerDataTransferThread(data, data.length, uploadSocket);//Set up file transfer thread
                        dx.start();
                    } catch (IOException ex) {
                        Logger.getLogger(ProtocallThreadV2.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    downloadCounter.incrementJavaCount();//Increment download counter
                    //Print client information
                    System.out.print(clientStream.displayDetail() + " has sucsessfully received the computer program\n");
                    System.out.print("Total downloads java: " + downloadCounter.getJavaCount() + "\n");
                }
                break;
                case 2: {
                    clientStream.sendString("Valid");
                    clientStream.sendString("myPicture.jpg");//Send file name
                    try {
                        file = new FileHandler("myPicture.jpg");
                    } catch (FileNotFoundException ex) {
                        Logger.getLogger(ProtocallThreadV2.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    data = file.readFromFile();
                    clientStream.sendString(Integer.toString(data.length));//Send file length
                    clientStream.sendString(Integer.toString(fileServerPort));//Send port
                    try {
                        StreamSocket uploadSocket = new StreamSocket(fileServer.accept());//Accept new file socket
                        dx = new ServerDataTransferThread(data, data.length, uploadSocket);//Set up file transfer thread
                        dx.start();
                    } catch (IOException ex) {
                        Logger.getLogger(ProtocallThreadV2.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    downloadCounter.incrementPictureCount();//Increment download counter
                    //Print client information
                    System.out.print(clientStream.displayDetail() + " has sucsessfully received the jpeg image\n");
                    System.out.print("Total downloads picture: " + downloadCounter.getPictureCount() + "\n");
                }
                break;
                case 3: {
                    clientStream.sendString("Valid");
                    clientStream.sendString("myBook.txt");//Send file name
                    try {
                        file = new FileHandler("myBook.txt");
                    } catch (FileNotFoundException ex) {
                        Logger.getLogger(ProtocallThreadV2.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    data = file.readFromFile();
                    clientStream.sendString(Integer.toString(data.length));//Send file length
                    clientStream.sendString(Integer.toString(fileServerPort));//Send port
                    try {
                        StreamSocket uploadSocket = new StreamSocket(fileServer.accept());//Accept new file socket
                        dx = new ServerDataTransferThread(data, data.length, uploadSocket);//Set up file transfer thread
                        dx.start();
                    } catch (IOException ex) {
                        Logger.getLogger(ProtocallThreadV2.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    downloadCounter.incrementBookCount();//Increment download counter
                    //Print client information
                    System.out.print(clientStream.displayDetail() + " has sucsessfully received the book\n");
                    System.out.print("Total downloads book: " + downloadCounter.getBookCount() + "\n");
                }
                break;
            }
            clientStream.sendString("Another? Y or N");
            do { //Another file/Description?  
                clientInput = clientStream.recieveString();
            } while (!validateClientAnotherInput(clientInput));

            if (clientInput.equalsIgnoreCase("N")) {
                try {
                    //Close connection if N
                    clientStream.kill();
                    fileServer.close();
                } catch (IOException ex) {
                    Logger.getLogger(ProtocallThreadV2.class.getName()).log(Level.SEVERE, null, ex);
                }
                //Client has disconnected
                System.out.print("Client " + clientStream.displayDetail() + " has disconnected\n");
                more = false;
            }
        }
    }
    // </editor-fold> 
}
